#include <stdlib.h>
#include <string>
#include <iostream>
#include <memory>
#include <rise/common/exmacros.h>
#include <rise/common/Log.h>
#include <rise/common/Exception.h>
#include <rise/common/DataEncoder.h>
#include <rise/common/StreamBuffer.h>
#include <staff/common/Value.h>
#include <staff/common/QName.h>
#include <staff/common/Attribute.h>
#include <staff/common/DataObject.h>
#include <staff-mq/client/Message.h>
#include <staff-mq/client/Subscriber.h>
#include "ComplexData.h"
#include "ComplexDataProxy.h"

class MyMessageHandler: public smq::MessageHandler
{
public:
  virtual void operator()(smq::Subscriber& rSubscriber, const smq::Message& rMsg)
  {
    std::cout << "Message arrived: \n"
        << "msgid: " << rMsg.sId << std::endl
        << "queue: " << rMsg.sQueue << std::endl
        << "publisher: " << rMsg.sPublisher << std::endl << std::endl;
    
    ComplexStruct stComplex;
    
    // deserializing struct from received data object
    rMsg.tdoMessage >> stComplex;

    // printing struct
    std::cout << "Struct:\n" <<
       "name: " << stComplex.sName << std::endl;
       
    for (StructList::const_iterator itStruct = stComplex.lsStructs.begin();
        itStruct != stComplex.lsStructs.end(); ++itStruct)
    {
      std::cout << " { nA: " << itStruct->nA << ", dB: " << itStruct->dB << ", sText: " << itStruct->sText << " }" << std::endl;
    }
  }
};


int main(int nArgs, char* szArgs[])
{
  std::string sServerHost = "127.0.0.1";
  unsigned short ushServerPort = 8768;

  for (int nArg = 1; nArg < nArgs; ++nArg)
  {
    if(szArgs[nArg])
    {
      const std::string& sArg = std::string(szArgs[nArg]);
      if (sArg.substr(0, 2) == "-s")
      {
        sServerHost = sArg.substr(2);
      }
      else
      if (sArg.substr(0, 2) == "-p")
      {
        ushServerPort = static_cast<unsigned short>(atoi(sArg.substr(2).c_str()));
      }
      else
      if (sArg.substr(0, 2) == "-h")
      {
        std::cerr << "Subscriber sample.\n\n"
            << szArgs[0] << "[ -h][ -s<Server host>][ -p<port>]\n\n";
        return 0;
      }
      else
      {
        std::cerr << "unknown arg: " << sArg << "\n";
        return 1;
      }
    }
  }

  try
  {
    MyMessageHandler tMessageHandler;

    smq::Subscriber tSubscriber;
    tSubscriber.Init("subscriber-complex", sServerHost, ushServerPort);
    tSubscriber.SetHandler(&tMessageHandler);

    std::cout << "subscribing to \"queue-complex\"" << std::endl;
    tSubscriber.Subscribe("queue-complex");

    tSubscriber.Start();
  }
  RISE_CATCH_ALL

  return 0;
}
